package com.fulihui.systemcore.service;

import com.fulihui.systemcore.api.PropertiesService;
import com.fulihui.systemcore.condition.PropertiesCondition;
import com.fulihui.systemcore.dal.dataobj.PropertiesExample;
import com.fulihui.systemcore.dto.PropertiesDTO;
import com.fulihui.systemcore.enums.EnvTypeEnum;
import com.fulihui.systemcore.repository.PropertiesRepository;
import com.fulihui.systemcore.request.prop.PropertiesDeleteRequest;
import com.fulihui.systemcore.request.prop.PropertiesPageRequest;
import com.fulihui.systemcore.request.prop.PropertiesQueryRequest;
import com.fulihui.systemcore.request.prop.PropertiesSaveRequest;
import com.fulihui.systemcore.util.error.SysServiceErrorEnum;
import org.apache.dubbo.config.annotation.Service;
import org.near.servicesupport.error.CommonServiceErrorEnum;
import org.near.servicesupport.request.TRequest;
import org.near.servicesupport.result.BaseResult;
import org.near.servicesupport.result.ResultBuilder;
import org.near.servicesupport.result.TMultiResult;
import org.near.servicesupport.result.TPageResult;
import org.near.toolkit.common.EnumUtil;
import org.near.toolkit.common.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static org.near.servicesupport.result.ResultBuilder.*;
import static org.near.toolkit.common.StringUtil.isNotBlank;
import static org.springframework.util.CollectionUtils.isEmpty;

/**
 * @author Created by Willard.Hu on 2016/6/1.
 */
@Service(version = "1.0.0")
public class PropertiesServiceImpl implements PropertiesService {
    private final transient Logger LOG = LoggerFactory.getLogger(PropertiesServiceImpl.class);
    @Autowired
    private PropertiesRepository   propertiesRepository;

    @Override
    public BaseResult save(PropertiesSaveRequest request) {
        if (!EnumUtil.inEnum(request.getEnvType(), EnvTypeEnum.class)) {
            LOG.error("环境类型{}不存在", request.getEnvType());
            return ResultBuilder.fail(BaseResult.class,
                CommonServiceErrorEnum.REQUEST_PARAMETER_ERROR);
        }
        PropertiesExample example = new PropertiesExample();
        example.createCriteria().andProdNameEqualTo(request.getProdName())
            .andEnvTypeEqualTo(request.getEnvType()).andPropKeyEqualTo(request.getKey());
        List<PropertiesDTO> propList = propertiesRepository.query(example);

        PropertiesDTO propDTO = new PropertiesDTO();
        BeanUtils.copyProperties(request, propDTO);
        if (CollectionUtils.isEmpty(propList)) {
            propertiesRepository.insert(propDTO);
        } else {
            PropertiesDTO propertiesDTO = propList.get(0);
            propDTO.setId(propertiesDTO.getId());
            boolean b = propertiesRepository.updateValue(propDTO);
            if (!b) {
                return ResultBuilder.fail(BaseResult.class, SysServiceErrorEnum.PROP_SAVE_ERROR);
            }
        }
        return succ(BaseResult.class);
    }

    @Override
    public BaseResult updateValue(PropertiesSaveRequest request) {
        if (!EnumUtil.inEnum(request.getEnvType(), EnvTypeEnum.class)) {
            LOG.error("环境类型{}不存在", request.getEnvType());
            return ResultBuilder.fail(BaseResult.class,
                CommonServiceErrorEnum.REQUEST_PARAMETER_ERROR);
        }


        PropertiesDTO propDTO = new PropertiesDTO();
        BeanUtils.copyProperties(request, propDTO);
        boolean b = propertiesRepository.updateValue(propDTO);
        if (!b) {
            return ResultBuilder.fail(BaseResult.class, SysServiceErrorEnum.PROP_SAVE_ERROR);
        }
        return succ(BaseResult.class);
    }

    @Override
    public BaseResult delete(PropertiesDeleteRequest request) {
        boolean b = propertiesRepository.delete(Integer.parseInt(request.getId()));
        if (!b) {
            return ResultBuilder.fail(BaseResult.class, SysServiceErrorEnum.PROP_DELETE_ERROR);
        }
        return succ(BaseResult.class);
    }

    @Override
    public TMultiResult<PropertiesDTO> query(TRequest<PropertiesCondition> request) {
        PropertiesCondition condition = request.getCondition();
        List<PropertiesDTO> propList;
        if (condition != null && StringUtil.isNotBlank(condition.getId())) {
            int id = Integer.parseInt(condition.getId());
            PropertiesDTO prop = propertiesRepository.queryByPK(id);
            if (prop != null) {
                propList = Collections.singletonList(prop);
            } else {
                propList = Collections.emptyList();
            }
        } else {
            PropertiesExample example;
            if (condition != null) {
                example = toExample(condition);
            } else {
                example = new PropertiesExample();
            }
            propList = propertiesRepository.query(example);
        }
        return succTMulti(propList);
    }

    @Override
    public TMultiResult<PropertiesDTO> queryMulti(PropertiesQueryRequest request) {
        List<PropertiesDTO> propList = propertiesRepository.query(toExample(request));
        return succTMulti(propList);
    }

    @Override
    public TPageResult<PropertiesDTO> queryPage(PropertiesPageRequest request) {
        List<PropertiesDTO> propList = propertiesRepository.queryPage(request);
        int totalCount = propertiesRepository.totalCount(request);
        return succTPage(propList, request.getPage(), request.getRows(), totalCount);
    }

    private PropertiesExample toExample(PropertiesQueryRequest request) {
        PropertiesExample example = new PropertiesExample();
        PropertiesExample.Criteria criteria = example.createCriteria();
        if (isNotBlank(request.getProdName())) {
            criteria.andProdNameEqualTo(request.getProdName());
        }
        if (isNotBlank(request.getEnvType())) {
            criteria.andEnvTypeEqualTo(request.getEnvType());
        }
        if (!isEmpty(request.getKey())) {
            criteria.andPropKeyIn(new ArrayList<>(request.getKey()));
        }
        return example;
    }

    private PropertiesExample toExample(PropertiesCondition condition) {
        PropertiesExample example = new PropertiesExample();
        PropertiesExample.Criteria criteria = example.createCriteria();
        if (isNotBlank(condition.getProdName())) {
            criteria.andProdNameEqualTo(condition.getProdName());
        }
        if (isNotBlank(condition.getEnvType())) {
            criteria.andEnvTypeEqualTo(condition.getEnvType());
        }
        if (isNotBlank(condition.getKey())) {
            criteria.andPropKeyEqualTo(condition.getKey());
        }
        return example;
    }
}
